<!-- 
    Document    : index
    Created on  : 27-aug-2008, 8:35:06
    Author      : jeroen ingelbrecht
    Thanks to	: Geert Vandamme, http://luke.breuer.com/tutorial/js_contextmenu.htm, http://luke.breuer.com/tutorial/javascript-drag-and-drop-tutorial.aspx, https://www.squarefree.com/bookmarklets/webdevel.html
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<title>Picaroo</title>
		<meta http-equiv="content-type" content="text/html;charset=utf-8" />
		<style type="text/css">
			.draggable, .comment, .menu {
				position: absolute;
				z-index: -3;
			}
			
			.comment, .menu {
				z-index: -2;
			}
			
			.menu {
				background-color: #CCCCCC;
				border: 1px solid black;
				padding: 0.2em;
			}
			
			.menu .menuItem {
				cursor: pointer;
			}
			
			.menu .limitedWidth {
				width: 200px;
			}
			
			.bordered {
				border: 1px solid black;
			}
			
			.moveCursor {
				cursor : move;
			}
			
			.editCursor {
				cursor: text;
			}
			
			.hidden {
				display: none;
			}
			
			.visible {
				display: block;
			}
			
			button.closeButton {
				float: right;
				background-color: #FF0000;
				border: 1px solid red;
				font-size: 10px;
				width: 10px%;
				vertical-align: middle;
			}
			
			.content {
				clear: all;
			}
		</style>
	</head>

	<body onload="init()">

		<div class="menu hidden" id="mainMenu">
			<span class="menuItem" onclick="showElement('addImageChoice')">Add an image</span>
			<hr />
			<span class="menuItem" onclick="showColourPicker('changeBackgroundColour')">Change backgroundcolour</span>
			
			<!--
				<hr />
				<span class="menuItem" onclick="showElement('save')">Save</span>
			 -->
			<hr />
			<span class="menuItem" onclick="printPage()">Print</span>
			<hr />
			<span class="menuItem" onclick="showElement('help')">Help</span>
			<hr />
			<span class="menuItem" onclick="showElement('about')">About</span>
		</div>
		
		<div class="menu hidden" id="addImageChoice">
					<input type="radio" checked="checked" name="source"  value="internetURL" id="radioInternetSource" onchange="enable('internetURL', 'sourceValue');"/> <!-- internet-->
					URL:&nbsp;
					<input type="text" id="internetURL" name="sourceValue" value="http://" />
				<br />
					<!-- 
					<input type="radio" name="source" value="filePath" id="radioLocalSource" onchange="enable('filePath', 'sourceValue');"/>local
					<input type="file" id="filePath" name="sourceValue"/>
					-->
				<br />
					<button onclick="addImage('source')">Add</button>
		</div>

		<div class="menu hidden" id="imageMenu">
			<p><button onclick="addComment('type your comment here')">add a commment</button></p>
			<table>
				<tbody>
					<tr>
						<td>width</td>
						<td><input type="checkbox" id="checkBoxPreserveRatio" checked="checked" onchange="changePreserveRatio('checkBoxPreserveRatio')" /></td>
						<td>height</td>
					</tr>
					<tr>
						<td>
							<input type="text" id="imageWidthInput" size="4" onkeyup="setWidth(document.getElementById('imageWidthInput').value )" />
						</td>
						<td>&nbsp;</td>
						<td>
							<input type="text" id="imageHeightInput" size="4" onkeyup="setHeight(document.getElementById('imageHeightInput').value )" />
						</td>
					</tr>
				</tbody>
			</table>
			<p><button onclick="deleteImage()">delete image</button></p>
		</div>
		
		<div class="menu hidden" id="colourPicker">
			
		</div>
		
		<div class="menu hidden limitedWidth" id="help">
			<p><button class="closeButton" onclick="hide('help')">x</button></p>
			<div class="content">
				<p><a href="http://code.google.com/p/picaroo/wiki/Help" name="help page" >Help page</a></p>
			</div>
		</div>
		
		<div class="menu hidden limitedWidth" id="about">
			<p><button class="closeButton" onclick="hide('about')">x</button></p>
			<p>
				Picaroo is a project that has known a slow start but has hopefully come to a stable release.
				Thanks to Geert Vandamme for the assignment and to the sources on the net for the ideas.
			</p>
		</div>
		
		<div class="menu hidden limitedWidth" id="save">
			<p><button class="closeButton" onclick="hide('save')">x</button></p>
			<p>
				The save as feature is possible if you're willing to follow a work-around. If you click on the button below, you'll see the source 
				of this page. Then, you'll have to copy/paste the source to a file of your choice. This is because there's no cross-browser solution for saving a 
				file using javascript.
				<button onclick="showSource()">save</button>
			</p>
		</div>

<!-- 
     	<p>
     		<button style="position: absolute; z-index: 1;" onclick="addImage('http://www.crapculture.ca/Images/Icons/Batman__5404.jpg')">Add image</button>
     	</p>
 -->
	<script type="text/javascript"><!--

		var util = new Util();
		var picarooCollection = new PicarooCollection();
		var htmlHelper = new HTMLHelper();
		var clickAndDragHelper = new ClickAndDragHelper();
		var colourPicker = new ColourPicker();

		var imageDivIdPrefix= "imageDiv_";
		var imageIdPrefix = "image_";
		var commentPrefix = "comment_";
		var commentDivIdPrefix = "commentDiv_"; //this is the prefix for the div that'll contain the comment. This id is followed by the imageID
		var commentContentIdPrefix = "commentContent_"; //this is the prefix for the contenteditable paragraph that'll contain the comment

		var selectedImage = null;
		
		//helpermethods
		function init()
		{
			
			//setting the heritages
			Util.prototype = new Object();
			//the prototype was initially new Image() but this led to problems: when adding a new image to the PicarooCollection, I instantiate var newImage with new PicarooImage(...)
			//but this did not create a new object at a new address. Instead, it took the initial created PicarooImageObject and changed the values of this Object!!! => not good
			PicarooImage.prototype = new Object();
			PicarooCollection.prototype = new Object();
			Comment.prototype = new Object();
			HTMLHelper.prototype = new Object();
			ClickAndDragHelper.prototype = new Object();
			ColourPicker.prototype = new Object();
			
			document.onmousedown = clickAndDragHelper.OnMouseDown;
		    document.onmouseup = clickAndDragHelper.OnMouseUp;

		    //avoid that the context menu is being showed when the user right clicks on the page
		    document.oncontextmenu = function(){return false;};

		}

		function addImage(checkboxGroupName, xCoordinate, yCoordinate, initialWidth, initialHeight)
		{
			var checkboxes = document.getElementsByName(checkboxGroupName);
			var element;
			var source;
			
			for(var i=0; i<checkboxes.length && !element; i++)
			{
				if(checkboxes[i].checked) {
					element = util.$(checkboxes[i].value);
				}
			}

			if(element.id == "internetURL")
			{
				source = element.value;
			} else if(element.id == "filePath") {
				//TODO: find a solution for this local stuff, not working in chrome and who can blame them
				//as this is after all a security violation
				
				alert(element.files[0].getAsDataURL());
				source = "file://" + element.value.replace(/\\/g,'/');
			}

			picarooCollection.addImage(source, xCoordinate, yCoordinate, initialWidth, initialHeight);
		}

		function deleteImage()
		{
			picarooCollection.deleteImage(selectedImage);
		}

		function addComment(commentText)
		{
			selectedImage.addComment(commentText);
		}

		function setWidth(number)
		{
			selectedImage.resize(number, selectedImage.getHeight());
			util.setInputWidthAndHeight(selectedImage.getWidth(), selectedImage.getHeight());
		}

		function setHeight(number)
		{
			selectedImage.resize(selectedImage.getWidth(), number);
			util.setInputWidthAndHeight(selectedImage.getWidth(), selectedImage.getHeight());
		}

		function showElement(id)
		{

			htmlHelper.show(id, clickAndDragHelper.getStartX(), clickAndDragHelper.getStartY());
		}

		function enable(idToEnable, disableName)
		{
			var elements = document.getElementsByName(disableName);
			for(var i=0; i<elements.length; i++)
			{
				var element = elements[i];
				if(element.id != idToEnable) {
					element.disabled = true;
				}
				else {
					element.disabled = false;
				}
			}
		}

		function printPage()
		{
			htmlHelper.hideAll();
			window.print();
		}

		function showColourPicker(functionName)
		{
			showElement("colourPicker");
			htmlHelper.fillColourPicker(functionName);
		}

		function changeBackgroundColour(colour)
		{
			document.body.style.backgroundColor = colour;
		}

		function changePreserveRatio(checkBoxId)
		{
			var el = util.$(checkBoxId);
			selectedImage.setPreserveRatio(el.checked);
		}

		function hide(HTMLElementId)
		{
			htmlHelper.hide(HTMLElementId);
		}

		function showSource() {
			alert(document.documentElement.innerHTML);	
			
		}

		/*
			Objects
			1. PicarooCollection
			2. Util
			3. PicarooImage
			4. Comment
			5. HTMLHelper
			6. ClickAndDragHelper
			7. ColourPicker
		*/

		/**
		* Class PicarooCollection
		**/
		function PicarooCollection()
		{
			this.images = new Array();

			//getters and evt setters for the attributes
			
			this.getImages = function()
			{
				return this.images;
			}

			this.getImage = function(imageId)
			{
				var image = null;
				var i = 0;
				var found = false;
				
				while(i < this.images.length && !found)
				{
					var imageHelp = this.images[i];
					if(imageHelp.getId() == imageId) {
						var image = imageHelp;
						found = true;
					}
					i++;
				}
					
				return image;
			}
			
			this.addImage = function(source, xCoordinate, yCoordinate, initialWidth, initialHeight)
			{
				var newImage = new PicarooImage(source, imageIdPrefix+util.getImageCounter(), xCoordinate, yCoordinate, initialWidth, initialHeight);

				util.addToImageCounter(1);
				
				htmlHelper.addImage(newImage);

				this.images.push(newImage);
			}

			this.deleteImage = function(picarooImageObject)
			{
				var found = false;
				var imageId = picarooImageObject.getId();
				for(var i=0; i<this.images.length && !found; i++) {
					if(this.images[i].getId() == imageId) {
						found = true;
						//remove the element from the array
						this.images.splice(i, 1);
						htmlHelper.removeElement(document.body, util.$(imageDivIdPrefix + imageId));
					}
				}
			}

		}

		/**
		* Class Util
		**/
		function Util()
		{
			this.imageCounter = 0;
			this.commentCounter = 0;
			this.startX = 0;
			this.startY = 0;

			/**
			*	add the number to the imagecounter
			**/
			this.addToImageCounter = function(number)
			{
				this.imageCounter += number;
			}

			/**
			* returns the imageCounter
			**/
			this.getImageCounter = function()
			{
				return this.imageCounter;
			}

			this.addToCommentCounter = function(number)
			{
				this.commentCounter += number;
			}
			
			this.getCommentCounter = function()
			{
				return this.commentCounter;
			}

			/**
			* returns the HTMLElement with this id
			**/
			this.$ = function(id)
			{
				return document.getElementById(id);
			}

			/**
			*  sets the starting coordinates 
			**/
			this.setStartingCoordinates = function(evt)
			{
				this.startX = evt.pageX;
				this.startY = evt.pageY;
			}

			/**
			* get the stopcoordinates
			**/
			this.getStopCoordinates = function(evt)
			{
				coordinates = [evt.pageX, evt.pageY];
				return coordinates;
			}

			/**
			* set the values of the input fields with ids imageWidthInput and imageHeightInput
			**/
			this.setInputWidthAndHeight = function(width, height)
			{
				util.$("imageWidthInput").value = width;
				util.$("imageHeightInput").value = height;
			}

			/**
			* returned the parsed value of an integer
			**/
			this.extractNumber = function(value)
			{
			    var n = parseInt(value);
				
			    return n == null || isNaN(n) ? 0 : n;
			}

			/**
			*checks if a certain element has a parentNode with a specified className
			**/
			this.hasParentWithClassName = function(element, className)
			{
				var endNode = document.getElementsByTagName("html")[0];
				var found = false;
				var node = element;
				
				while(node != endNode && !found)
				{
					if(node.className && node.className.indexOf(className) != -1) {
						found = true;
					} else node = node.parentNode;
				}
				return found;
			}
			
			return true;
		}

		/**
		* Class PicarooImage
		**/
		function PicarooImage(source, id, xCoordinate, yCoordinate, initialWidth, initialHeight)
		{
			this.src = source;
			this.imageObject = new Image();
			this.imageObject.onload = setWidthAndHeight(this.imageObject);
			this.imageObject.src = source;
			
			this.xCoordinate = xCoordinate?xCoordinate:0;
			this.yCoordinate = yCoordinate?yCoordinate:0;
			this.initialWidth = initialWidth?initialWidth:this.imageObject.width;
			this.initialHeight = initialHeight?initialHeight:this.imageObject.height;
			this.id = id;
			this.comments = new Array();

			this.preserveRatio = true;

			//getters and setters for the attributes
			this.getSrc = function()
			{
				return this.src;
			}

			this.getXCoordinate = function()
			{
				return this.xCoordinate?this.xCoordinate:0;
			}

			this.setXCoordinate = function(xCoordinate)
			{
				this.xCoordinate = xCoordinate;
			}

			this.getYCoordinate = function()
			{
				return this.yCoordinate?this.yCoordinate:0;
			}

			this.setYCoordinate = function(yCoordinate)
			{
				this.yCoordinate = yCoordinate;
			}

			this.getInitialWidth = function()
			{
				return this.initialWidth;
			}

			this.getInitialHeight = function()
			{
				return this.initialHeight;
			}

			this.getWidth = function()
			{
				return this.imageObject.width;
			}

			this.getHeight = function()
			{
				return this.imageObject.height;
			}			

			this.getId = function()
			{
				return this.id;
			}

			this.getComments = function()
			{
				return this.comments;
			}

			this.getImageObject = function()
			{
				return this.imageObject;
			}

			function setWidthAndHeight(image)
			{
				this.width = image.width;
				this.height = image.height;
			}

			this.setPreserveRatio = function(b)
			{
				alert('ok');
				this.preserveRatio = b;
			}

			this.isPreserveRatio = function()
			{
				return this.preserveRatio;
			}
			
			/* Functionality 
				1.	rotate(degree)
				2.	resize(width, height)
				3. reposition(event)
			*/
			this.rotate = function(degree)
			{
				alert('rotate(degree) is not implemented yet');
				//TODO implement
			};

			this.resize = function(width, height)
			{
				if(this.preserveRatio)
				{
					var ratio = this.imageObject.width/this.imageObject.height;
				
					this.imageObject.width = width==this.imageObject.width?ratio*height:width;
					this.imageObject.height = height==this.imageObject.height?width/ratio:height;
				} else if(!this.preserveRatio) {
					this.imageObject.width = width;
					this.imageObject.height = height;
				}
				
				util.$(this.id).width = this.imageObject.width;
				util.$(this.id).height = this.imageObject.height;
			}

			this.reposition = function(evt)
			{
				coordinates = util.getStopCoordinates(evt);
				this.xCoordinate = coordinates[0];
				this.yCoordinate = coordinates[1];
				util.$(this.id).setAttribute("style", "position: absolute; top: "+this.xCoordinate+"; left: "+this.yCoordinate+"");
			}

			this.addComment = function(commentText)
			{

				var commentId = commentPrefix + util.getCommentCounter();
				util.addToCommentCounter(1);
				
				var comment = new Comment(this, commentText, commentId);
				
				this.comments.push(comment);

				htmlHelper.addComment(this, comment);
			}

			this.toString = function()
			{
				return '<img src="'+this.src+'" width="'+this.width+'" height="'+this.height+'" class="draggable" \/>';
			}

			return true;
		}

		/**
		* Class Comment
		**/
		function Comment(image, text, id)
		{
			this.id = id;
			this.image = image;
			this.text = text;
			this.xCoordinate;
			this.yCoordinate;

			this.getId = function()
			{
				return this.id;
			}

			this.getImage = function()
			{
				return this.image;
			}

			this.getText = function()
			{
				return this.text;
			}
			
			return true;
		}

		/**
		* Class HTMLHelper
		* Class to write away any HTML and add it to the document
		**/
		function HTMLHelper()
		{

			this.addImage = function(picarooImageObject)
			{
				var newDiv = document.createElement('div');
				var newImage = document.createElement('img');

				newDiv.setAttribute("id", imageDivIdPrefix + picarooImageObject.getId());
				
				newImage.setAttribute("src", picarooImageObject.getSrc());
					//put the next two lines in comments because these values were not correct when browser cache was empty
				//newImage.setAttribute("width", picarooImageObject.getWidth());
				//newImage.setAttribute("height", picarooImageObject.getHeight());
				newImage.setAttribute("id", picarooImageObject.getId());
				newImage.setAttribute("class", "draggable");
				newDiv.appendChild(newImage);

				document.body.appendChild(newDiv);
			}
			
			this.addComment = function(picarooImageObject, commentObject)
			{
				//TODO move this code to a more central class that handles the HTML output
				/* example
					<div class="draggable comment moveCursor" id="commentDiv_image_0" style="left: 103px; top: 205px; ">
						<p contenteditable="true" id="commentContent_image_0" class="editCursor">testComment</div></p>
					</div>
				*/
				var thisElement = util.$(picarooImageObject.getId() );
				var newDiv = document.createElement('div');
				newDiv.setAttribute('class', 'draggable comment moveCursor');
				newDiv.setAttribute('id', commentDivIdPrefix+commentObject.getId());
				
				var newPara = document.createElement('p');
				newPara.setAttribute("contenteditable", true);
				newPara.setAttribute("id", commentContentIdPrefix + commentObject.getId() );
				newPara.setAttribute('class', 'editCursor');

				newDiv.appendChild(newPara);
				thisElement.parentNode.appendChild(newDiv);
				

				var divElement = util.$(commentDivIdPrefix + commentObject.getId() );
				divElement.style.top = thisElement.style.top;
				divElement.style.left = thisElement.style.left;

				pElement = util.$(commentContentIdPrefix + commentObject.getId() );
				pElement.innerHTML = commentObject.getText();
				
			}

			this.hideAll = function()
			{
				var elementsToHideArray = getElementsByClassName('visible');
				swapClassName(elementsToHideArray, 'visible', 'hidden');
			}
			
			this.showImageMenu = function()
			{
				htmlHelper.show('imageMenu', clickAndDragHelper.getStartX(), clickAndDragHelper.getStartY());
			}

			this.showMainMenu = function()
			{
				htmlHelper.show('mainMenu', clickAndDragHelper.getStartX(), clickAndDragHelper.getStartY());
			}

			//if you declare a method with var instead of this, the method is a private method
			this.show = function(id, x, y)
			{
				//show the element that needs to be shown
				var element = util.$(id);
				swapClassName([element], 'hidden', 'visible');
				element.style.left = (x?x:0) +'px';
				element.style.top = (y?y:0) +'px';
			}

			this.hide = function(id)
			{
				swapClassName([util.$(id)], 'visible', 'hidden');
			}

			var getElementsByClassName = function(classname, node)
			{ 
				if (!node){
					node = document.getElementsByTagName('body')[0];
				}
				var a = [], re = new RegExp('\\b' + classname + '\\b');
				var els = node.getElementsByTagName('*');
				for (var i = 0, j = els.length; i < j; i++) { 
					if ( re.test(els[i].className) ) {
						a.push(els[i]);
					}
				}
				return a;
			}

			var swapClassName = function(HTMLElementArray, from, to)
			{
				for(var i=0; i<HTMLElementArray.length; i++)
				{
					var HTMLElement = HTMLElementArray[i];
					
					if(HTMLElement.className.indexOf(from) != -1)
					{
						HTMLElement.className = HTMLElement.className.replace(new RegExp(from), to);
					}
				}	
			}

			this.fillColourPicker = function(functionName)
			{
				var colourArray = colourPicker.getColours();
				var colourPickerElement = util.$("colourPicker");

				var innerHTML = "<table>";
				var i = 0;
				while(i<colourArray.length)
				{
					innerHTML += "<tr>";
					for(var numberOfColumns = 0; numberOfColumns < 6; numberOfColumns++)
					{
						innerHTML += "<td class='menuItem' style='background-color: #" +colourArray[i]+ "' onclick='"+functionName+"(\"#"+colourArray[i]+"\")'> #" +colourArray[i]+ " </td>";
						i++;
					}
					innerHTML += "</tr>";
				}

				innerHTML += "<table>";
				colourPickerElement.innerHTML = innerHTML;
			}

			/**remove an element from the document
			*	parentElement: the element from which the childelement has to be removed
			*	childElement: the element that needs to be removed
			**/
			this.removeElement = function(parentElement, childElement)
			{
				parentElement.removeChild(childElement);
			}
			return true;
		}

		/**
		* 6. CLickAndDragHelper
		* This class handles any clicks and dragmoves in the window
		**/
		function ClickAndDragHelper()
		{

			this._startX;            // mouse starting positions
			this._startY;
			this._offsetX;           // current element offset
			this._offsetY;
			this._dragElement = null;           // needs to be passed from OnMouseDown to OnMouseMove
			this._oldZIndex = -1;         // we temporarily increase the z-index during drag

			/* getters and setters */
			this.getStartX = function()
			{
				return this._startX;
			}

			this.setStartX = function(startX)
			{
				this._startX = startX;
			}

			this.getStartY = function()
			{
				return this._startY;
			}

			this.setStartY = function(startY)
			{
				this._startY = startY;
			}

			this.getOffsetX = function()
			{
				return this._offsetX;
			}

			this.setOffsetX = function(offsetX)
			{
				this._offsetX = offsetX;
			}

			this.getOffsetY = function()
			{
				return this._offsetY;
			}

			this.setOffsetY = function(offsetY)
			{
				this._offsetY = offsetY;
			}

			this.getDragElement = function()
			{
				return this._dragElement;
			}

			this.setDragElement = function(dragElement)
			{
				this._dragElement = dragElement;
			}

			this.getOldZIndex = function()
			{
				return this._oldZIndex;
			}

			this.setOldZIndex = function(oldZIndex)
			{
				this._oldZIndex = oldZIndex;
			}

			this.isLeftClick = function(e)
			{
				// IE is retarded and doesn't pass the event object
			    if (e == null) {
			        e = window.event; 
			    }

			 	// for IE, left click == 1
			    // for Firefox, left click == 0
			    return (e.button == 1 && window.event != null) || e.button == 0;
			}
		
			this.isRightClick = function(e)
			{
				return e.button == 2;
			}
			
			function onMouseMove(e)
			{
				if (e == null) {
			        var e = window.event; 
			    }
			    
			    // this is the actual "drag code"
			    this._dragElement.style.left = (clickAndDragHelper.getOffsetX() + e.clientX - clickAndDragHelper.getStartX()) + 'px';
			    this._dragElement.style.top = (clickAndDragHelper.getOffsetY() + e.clientY - clickAndDragHelper.getStartY()) + 'px';   
			}
			
			this.OnMouseDown = function(e)
			{
				
				// IE is retarded and doesn't pass the event object
			    if (e == null) {
			        e = window.event; 
			    }
			    
			    // IE uses srcElement, others use target
			    var target = e.target != null ? e.target : e.srcElement;
			    
			 	// grab the mouse position
			 	clickAndDragHelper.setStartX(e.clientX);
		        clickAndDragHelper.setStartY(e.clientY);
		        
		        // grab the clicked element's position
		        clickAndDragHelper.setOffsetX(util.extractNumber(target.style.left));
		        clickAndDragHelper.setOffsetY(util.extractNumber(target.style.top));

				//hide all the visible items, except when the user is clicking on a menu, otherwise
				//the action is not handled
				if(!util.hasParentWithClassName(target, "menu"))
				{
					//hide all the visible div
					htmlHelper.hideAll();
				}
				
			    //if rightclick
				if(clickAndDragHelper.isRightClick(e))
				{
					//if the user has clicked on an image
					if(target.tagName.toLowerCase() == "img")
					{
						//retrieve the image from the list of images in the picarooCollection
						selectedImage = picarooCollection.getImage(target.id);

						//show the imagemenu
						htmlHelper.showImageMenu();
						
						//set the values of the inputfields inputWidth and inputHeight
						util.setInputWidthAndHeight(selectedImage.getWidth(), selectedImage.getHeight());
					}

					else{
						//show the main menu
						htmlHelper.showMainMenu();
					}
				}
			    
			    else if ( clickAndDragHelper.isLeftClick(e) && target.className.indexOf('draggable') != -1) // -1 to take care of the possibility that the classname exists of multiple classes
			    {
			        // bring the clicked element to the front while it is being dragged
			        this._oldZIndex = target.style.zIndex;
			        target.style.zIndex = 10000;

			        clickAndDragHelper.setDragElement(target);
					this._dragElement = target;
			        
			        // tell our code to start moving the element with the mouse
			        document.onmousemove = onMouseMove;
			        			        
			        // cancel out any text selections
			        document.body.focus();

			        // prevent text selection in IE
			        document.onselectstart = function () { return false; };
			        // prevent IE from trying to drag an image
			        target.ondragstart = function() { return false; };
			        
			        // prevent text selection (except IE)
			        return false;
				}
			}
			
			this.OnMouseUp = function(evt)
			{
				if (this._dragElement != null)
			    {
					this._dragElement.style.zIndex = this._oldZIndex;

			        //TODO: how to make sure the children are being moved as well
			        //Note that this must be a generic setup!! so it must serve for the images, the comments
			        //but it must also be used by third-parties!!!
			        
			        // we're done with these events until the next OnMouseDown
			        document.onmousemove = null;
			        document.onselectstart = null;
			        this._dragElement.ondragstart = null;

			        // this is how we know we're not dragging      
			        this._dragElement = null;
			    }
			}
			
			return true;
		}

		/**
		* 7. Class ColourPicker
		* The only purpose of this class is to provide a way to create a table of colours of which
		* the user can pick one for whatever the purpose may be
		**/
		function ColourPicker()
		{
			this.colours = ['0', '3', '6', '9', 'C', 'F'];

			/**
			* this function returns the 216 websafe colourcodes
			**/
			this.getColours = function()
			{
				var colourArray = new Array();
				for(var r=0; r < this.colours.length; r++)
				{
					for(var g=0; g < this.colours.length; g++)
					{
						for(var b=0; b<this.colours.length; b++)
						{
							var red = this.colours[r] + this.colours[r];
							var green = this.colours[g] + this.colours[g];
							var blue = this.colours[b] + this.colours[b];
							
							colourArray.push(red + green + blue);
						}
					}
				}
				return colourArray;
			}

			return true;
		}
		
	
	--></script>
	
	</body>
</html>